/**
 * 
 */
package eTaxi;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

/**
 * Questo thread del Taxi si occupa di gestire le invocazioni dei metodi remoti
 * offerti dall'oggetto remoto di tipo Bank. Nel suo ciclo di vita il thread
 * attende che UserHandler lo sblocchi al momento in cui ha ricevuto i parametri
 * della prenotazione dal cliente. Con una terza variabile "monitor" (il campo
 * free dell'oggetto TaxiProfile) impedisce che UserHandler torni ad accettare
 * richieste dai clienti se prima non sono state completate le richieste
 * all'oggetto remoto.
 * 
 */

public class BankHandler extends Thread {

    private TaxiProfile tp;

    static E_Bank bank;

    String username;

    int req_ride;

    int userPort;

    Integer res_number;

    protected Lock lock;

    protected Lock lock2;

    UserHandler userhandler;

    int res_int;

    public BankHandler(TaxiProfile t, Lock l, Lock l2) {
        super();

        this.tp = t;
        res_number = new Integer(-1);
        this.lock = l;
        this.lock2 = l2;

    }

    public void run() {

        while (true) {

            /*
             * Il metodo run() si blocca subito aspettando che il thread che
             * gestisce le comunicazioni con il cliente abbia ricevuto dal
             * cliente stesso i dettagli sulla prenotazione.
             */

            userhandler.lock.go();// prova a togliere userhandler

            tp.setFree(false);

            String username = userhandler.ride_details[1];

            int req_ride = Integer.parseInt(userhandler.ride_details[4]);

            String cct = userhandler.ride_details[5];

            try {
                /*
                 * Il taxi si collega alla banca
                 * 
                 */

                bank = (E_Bank) Naming.lookup("//" + cct + "/bank");
                System.out
                        .println("Il Taxi si è correttamente collegato al servizio bancario");

                

                res_number = new Integer(bank.check(username, req_ride));

                /*
                 * avendo ricevuto dalla banca la risposta al metodo check,
                 * sblocco userhandler
                 * 
                 */

                lock2.setLock(false); 

                if (res_number.intValue() == 0) {
                    System.out.println("La banca ha negato la transazione!");

                    /*
                     * Avendo la banca negato la transazione resetto la
                     * variabile free a true, e faccio lo stesso in caso di
                     * eccezione catturata.
                     */

                    tp.setFree(true);
                    lock2.setLock(true);

                }

                else {

                    /*
                     * La banca ha dato il via libera, non resta che attendere
                     * la notifica
                     * 
                     */

                    while (bank.notify(res_number.intValue()) == 0) {
                        try {
                            System.out
                                    .println("Il Taxi sta aspettando la notifica da parte della banca.");
                            Thread.sleep(500);
                        } catch (InterruptedException e) {

                            tp.setFree(true);
                            lock2.setLock(true);

                        }
                    }

                    tp.setFree(true);
                    System.out.println("Taxi: NOTIFY OK");
                    
                    /*
                     * Al termine delle comunicazioni con la banca si resettano
                     * le due variabili con cui BankHandler si sincronizza con
                     * UserHandler; questa operazione si effettua anche in caso
                     * di eccezioni.
                     */

                    lock2.setLock(true);

                }// fine notify()

            } // fine try sui metodi RMI

            catch (MalformedURLException mue) {

                tp.setFree(true);

                lock2.setLock(true);

                System.out
                        .println("Eccezione nella invocazione del metodo RMI: "
                                + mue);
            }

            catch (NotBoundException nbe) {

                tp.setFree(true);

                lock2.setLock(true);

                System.out
                        .println("Eccezione nella invocazione del metodo RMI: "
                                + nbe);
            } catch (RemoteException re) {
                tp.setFree(true);

                lock2.setLock(true);

                System.out
                        .println("Eccezione nella invocazione del metodo RMI: "
                                + re);

            }

        }
    } // fine run

    protected void init(UserHandler uh) {
        this.userhandler = uh;

    }

}// fine classe

